﻿
using System;
using DocumentFormat.OpenXml;

namespace Fantom
{
	/// <summary>
	/// 厘米
	/// </summary>
	public readonly struct Cm
	{
		public Cm(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator Cm(double value)
		{
			return new Cm(value);
		}

		public override string ToString()
		{
			return Value.ToString();
		}

		#region operators overloads
		public static bool operator <(Cm v1, Cm v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Cm v1, Cm v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Cm v1, Cm v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Cm v1, Cm v2)
		{
			return v1.Value != v2.Value;
		}

		public static Cm operator +(Cm v1, Cm v2)
		{
			return new Cm(v1.Value + v2.Value);
		}

		public static Cm operator -(Cm v1, Cm v2)
		{
			return new Cm(v1.Value - v2.Value);
		}

		public static Cm operator /(Cm v, double div)
		{
			return new Cm(v.Value / div);
		}

		public static Cm operator *(Cm v, double multi)
		{
			return new Cm(v.Value * multi);
		}

		public static Cm operator *(double multi, Cm v)
		{
			return new Cm(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Cm)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion
	}

	/// <summary>
	/// Office特有也是最主要的格式
	/// </summary>
	public readonly struct Emu
	{
		public Emu(int value)
		{
			Value = value;
		}

		public Emu(long value)
		{
			Value = value;
		}

		public Emu(Int32Value value)
		{
			Value = value.Value;
		}

		public Emu(UInt32Value value)
		{
			Value = value.Value;
		}

		public Emu(double value)
		{
			Value = (long)value;
		}

		public Emu(string value)
		{
			Value = (long)(double.Parse(value));
		}

		public long Value { get; }

		public static implicit operator Emu(int value)
		{
			return new Emu(value);
		}

		public static implicit operator Emu(Int32Value value)
		{
			return new Emu(value);
		}

		public static implicit operator Emu(UInt32Value value)
		{
			return new Emu(value);
		}

		public static implicit operator Emu(long value)
		{
			return new Emu(value);
		}

		public static implicit operator Emu(double value)
		{
			return new Emu(value);
		}

		public override string ToString()
		{
			return Value.ToString();
		}

		public Pixel ToPixel()
		{
			return Primitive.UnitConverter.ToPixel(this);
		}

		/// <summary>
		/// 常用于画面尺寸数据的描述。
		/// </summary>
		public double ToPixelValue()
		{
			return Value * Primitive.UnitConverter.DefaultDpi / 914400;
		}

		/// <summary>
		/// 转换成角度制。
		/// </summary>
		/// <returns>返回值在0°~360°之间。</returns>
		public double ToAngle()
		{
			return Math.Round(Value * 360d / TwoPi, 5);
		}

		/// <summary>
		/// 转换为字体尺寸值。
		/// </summary>
		/// <returns></returns>
		public double ToFontSize()
		{
			return Value / _fsz1.Value;
		}

		/// <summary>
		/// 时间相关的值转换为秒数。
		/// </summary>
		/// <returns></returns>
		public double ToSeconds()
		{
			return Value / 1000d;
		}

		/// <summary>
		/// 将其转换为 .NET 中统一的时间度量单位。
		/// </summary>
		/// <returns></returns>
		public TimeSpan ToTimeSpan()
		{
			return TimeSpan.FromMilliseconds(Value);
		}

		/// <summary>
		/// 获得一个百分比。
		/// </summary>
		/// <returns></returns>
		public double ToPercent()
		{
			return 1.0d * Value / _100.Value;
		}

		/// <summary>
		/// 获得其正确的浮点值。
		/// </summary>
		/// <returns></returns>
		public double ToDouble()
		{
			return Value / 1000d;
		}

		#region operators overloads
		public static bool operator <(Emu v1, Emu v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Emu v1, Emu v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Emu v1, Emu v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Emu v1, Emu v2)
		{
			return v1.Value != v2.Value;
		}

		public static Emu operator +(Emu v1, Emu v2)
		{
			return new Emu(v1.Value + v2.Value);
		}

		public static Emu operator -(Emu v1, Emu v2)
		{
			return new Emu(v1.Value - v2.Value);
		}

		public static Emu operator /(Emu v, double div)
		{
			return new Emu(v.Value / div);
		}

		public static Emu operator *(Emu v, double multi)
		{
			return new Emu(v.Value * multi);
		}

		public static Emu operator *(double multi, Emu v)
		{
			return new Emu(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Emu)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion


		/// <summary>
		/// 绝对 0 值。
		/// </summary>
		public static Emu Num0 => _0;
		private static Emu _0 = new Emu(0);


		/// <summary>
		/// 本值 12700，pixel 值为 1。
		/// </summary>
		public static Emu Val1 => _v1;
		private static Emu _v1 = new Emu(12700);


		/// <summary>
		/// 本值为 100000。
		/// </summary>
		public static Emu Num100 => _100;
		private static Emu _100 = new Emu(100000);

		/// <summary>
		/// 字体格式值。其可以通过 <see cref="ToFontSize"/> 转换为正确的原值 1.0d。
		/// </summary>
		public static Emu FontSize1 => _fsz1;
		private static Emu _fsz1 = new Emu(100);

		/// <summary>
		/// 一秒时间。其可以通过 <see cref="ToSeconds"/> 转换为正确的原值 1.0d，或通过 <see cref="ToTimeSpan"/> 转换为正确的时间值 00:00:01.000 。
		/// </summary>
		public static Emu Seconds1 => _sec1;
		private static Emu _sec1 = new Emu(1000);

		/// <summary>
		/// 零秒时间。其可以通过 <see cref="ToSeconds"/> 转换为正确的原值 0.0d，或通过 <see cref="ToTimeSpan"/> 转换为正确的时间值 00:00:00.000 。
		/// </summary>
		public static Emu Seconds0 => _0;

		/// <summary>
		/// 1% 百分之一的表示形式。其可以通过 <see cref="ToPercent"/> 转换为正确的原值 0.01d。
		/// </summary>
		public static Emu Precent1 => _p1;
		private static Emu _p1 = new Emu(1000);
		/// <summary>
		/// 100% 百分之百的表示形式。其可以通过 <see cref="ToPercent"/> 转换为正确的原值 1.0d。
		/// </summary>
		public static Emu Percent100 => _100;

		/// <summary>
		/// 1000% 帕森帕脱的表示形式。其可以通过 <see cref="ToPercent"/> 转换为正确的原值 10.0d，但是改变不了吃瘪的命运。
		/// </summary>
		public static Emu Percent1000 => _100 * 10;

		/// <summary>
		/// 浮点数 1 的 <see cref="Emu"/> 表示形式。其可以通过 <see cref="ToDouble"/> 转换为正确的原值 1.0d。
		/// </summary>
		public static Emu Double1 => _d1;
		private static Emu _d1 = new Emu(1000);

		/// <summary>
		/// 角度制角度 1°。其可以通过 <see cref="ToAngle"/> 转换为正确的角度制（0°~360°）的原值 1.0d 。
		/// </summary>
		public static Emu Degree1 => _deg1;
		private static Emu _deg1 = new Emu(60000);

		/// <summary>
		/// 角度制角度 360°。其可以通过 <see cref="ToAngle"/> 转换为正确的角度制（0°~360°）的原值 360.0d 。
		/// </summary>
		public static Emu Degree360 => _deg360;
		private static Emu _deg360 = new Emu(21600000);


		/// <summary>
		/// 角度制角度 360°，对应弧度 2 PI。其可以通过 <see cref="ToAngle"/> 转换为正确的角度制（0°~360°）的原值 360.0d 。
		/// </summary>
		public static long TwoPi => 21600000;

		/// <summary>
		/// 角度制角度 180°，对应弧度 PI。其可以通过 <see cref="ToAngle"/> 转换为正确的角度制（0°~360°）的原值 180.0d 。
		/// </summary>
		public static long Pi => 10800000;

		public static Emu Parse(string valueString)
		{
			if (valueString == "indefinite")
				return 0;
			return long.Parse(valueString);
		}

	}

	/// <summary>
	/// 像素
	/// </summary>
	public readonly struct Pixel
	{
		public Pixel(long value)
		{
			Value = (double)value;
		}

		public Pixel(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator Pixel(long value)
		{
			return new Pixel(value);
		}

		public static implicit operator Pixel(double value)
		{
			return new Pixel(value);
		}

		public Emu ToEmu()
		{
			return Primitive.UnitConverter.ToEmu(this);
		}

		public override string ToString()
		{
			return Math.Round(Value, 4).ToString();
		}

		#region operators overloads
		public static bool operator <(Pixel v1, Pixel v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Pixel v1, Pixel v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Pixel v1, Pixel v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Pixel v1, Pixel v2)
		{
			return v1.Value != v2.Value;
		}

		public static Pixel operator +(Pixel v1, Pixel v2)
		{
			return new Pixel(v1.Value + v2.Value);
		}

		public static Pixel operator -(Pixel v1, Pixel v2)
		{
			return new Pixel(v1.Value - v2.Value);
		}

		public static Pixel operator /(Pixel v, double div)
		{
			return new Pixel(v.Value / div);
		}

		public static Pixel operator *(Pixel v, double multi)
		{
			return new Pixel(v.Value * multi);
		}

		public static Pixel operator *(double multi, Pixel v)
		{
			return new Pixel(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Pixel)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion
	}
}
namespace Fantom.Primitive
{

	#region units
	/// <summary>
	/// 不知道是什么类型
	/// </summary>
	public readonly struct Dxa
	{
		public Dxa(double value)
		{
			Value = value;
		}

		public double Value { get; }
		public static implicit operator Dxa(double value)
		{
			return new Dxa(value);
		}

		public override string ToString()
		{
			return Value.ToString();
		}

		#region operators overloads
		public static bool operator <(Dxa v1, Dxa v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Dxa v1, Dxa v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Dxa v1, Dxa v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Dxa v1, Dxa v2)
		{
			return v1.Value != v2.Value;
		}

		public static Dxa operator +(Dxa v1, Dxa v2)
		{
			return new Dxa(v1.Value + v2.Value);
		}

		public static Dxa operator -(Dxa v1, Dxa v2)
		{
			return new Dxa(v1.Value - v2.Value);
		}

		public static Dxa operator /(Dxa v, double div)
		{
			return new Dxa(v.Value / div);
		}

		public static Dxa operator *(Dxa v, double multi)
		{
			return new Dxa(v.Value * multi);
		}

		public static Dxa operator *(double multi, Dxa v)
		{
			return new Dxa(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Dxa)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}

	public readonly struct Emu32
	{
		public Emu32(int value)
		{
			Value = value;
		}

		public Emu32(double value)
		{
			Value = (int)value;
		}

		public int Value { get; }


		public static implicit operator Emu32(int value)
		{
			return new Emu32(value);
		}

		public static implicit operator Emu32(double value)
		{
			return new Emu32(value);
		}

		public override string ToString()
		{
			return Value.ToString();
		}

		#region operators overloads
		public static bool operator <(Emu32 v1, Emu32 v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Emu32 v1, Emu32 v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Emu32 v1, Emu32 v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Emu32 v1, Emu32 v2)
		{
			return v1.Value != v2.Value;
		}

		public static Emu32 operator +(Emu32 v1, Emu32 v2)
		{
			return new Emu32(v1.Value + v2.Value);
		}

		public static Emu32 operator -(Emu32 v1, Emu32 v2)
		{
			return new Emu32(v1.Value - v2.Value);
		}

		public static Emu32 operator /(Emu32 v, double div)
		{
			return new Emu32(v.Value / div);
		}

		public static Emu32 operator *(Emu32 v, double multi)
		{
			return new Emu32(v.Value * multi);
		}

		public static Emu32 operator *(double multi, Emu32 v)
		{
			return new Emu32(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Emu32)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}


	public readonly struct FiftiethsOfAPercent
	{
		public FiftiethsOfAPercent(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator FiftiethsOfAPercent(double value)
		{
			return new FiftiethsOfAPercent(value);
		}

		#region operators overloads
		public static bool operator <(FiftiethsOfAPercent v1, FiftiethsOfAPercent v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(FiftiethsOfAPercent v1, FiftiethsOfAPercent v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(FiftiethsOfAPercent v1, FiftiethsOfAPercent v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(FiftiethsOfAPercent v1, FiftiethsOfAPercent v2)
		{
			return v1.Value != v2.Value;
		}

		public static FiftiethsOfAPercent operator +(FiftiethsOfAPercent v1, FiftiethsOfAPercent v2)
		{
			return new FiftiethsOfAPercent(v1.Value + v2.Value);
		}

		public static FiftiethsOfAPercent operator -(FiftiethsOfAPercent v1, FiftiethsOfAPercent v2)
		{
			return new FiftiethsOfAPercent(v1.Value - v2.Value);
		}

		public static FiftiethsOfAPercent operator /(FiftiethsOfAPercent v, double div)
		{
			return new FiftiethsOfAPercent(v.Value / div);
		}

		public static FiftiethsOfAPercent operator *(FiftiethsOfAPercent v, double multi)
		{
			return new FiftiethsOfAPercent(v.Value * multi);
		}

		public static FiftiethsOfAPercent operator *(double multi, FiftiethsOfAPercent v)
		{
			return new FiftiethsOfAPercent(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (FiftiethsOfAPercent)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}

	public readonly struct HalfPoint
	{
		public HalfPoint(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator HalfPoint(double value)
		{
			return new HalfPoint(value);
		}

		#region operators overloads
		public static bool operator <(HalfPoint v1, HalfPoint v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(HalfPoint v1, HalfPoint v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(HalfPoint v1, HalfPoint v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(HalfPoint v1, HalfPoint v2)
		{
			return v1.Value != v2.Value;
		}

		public static HalfPoint operator +(HalfPoint v1, HalfPoint v2)
		{
			return new HalfPoint(v1.Value + v2.Value);
		}

		public static HalfPoint operator -(HalfPoint v1, HalfPoint v2)
		{
			return new HalfPoint(v1.Value - v2.Value);
		}

		public static HalfPoint operator /(HalfPoint v, double div)
		{
			return new HalfPoint(v.Value / div);
		}

		public static HalfPoint operator *(HalfPoint v, double multi)
		{
			return new HalfPoint(v.Value * multi);
		}

		public static HalfPoint operator *(double multi, HalfPoint v)
		{
			return new HalfPoint(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (HalfPoint)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}

	/// <summary>
	/// 英寸
	/// </summary>
	public readonly struct Inch
	{
		public Inch(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator Inch(double value)
		{
			return new Inch(value);
		}

		#region operators overloads
		public static bool operator <(Inch v1, Inch v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Inch v1, Inch v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Inch v1, Inch v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Inch v1, Inch v2)
		{
			return v1.Value != v2.Value;
		}

		public static Inch operator +(Inch v1, Inch v2)
		{
			return new Inch(v1.Value + v2.Value);
		}

		public static Inch operator -(Inch v1, Inch v2)
		{
			return new Inch(v1.Value - v2.Value);
		}

		public static Inch operator /(Inch v, double div)
		{
			return new Inch(v.Value / div);
		}

		public static Inch operator *(Inch v, double multi)
		{
			return new Inch(v.Value * multi);
		}

		public static Inch operator *(double multi, Inch v)
		{
			return new Inch(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Inch)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}

	/// <summary>
	/// 毫米
	/// </summary>
	public readonly struct Mm
	{
		public Mm(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator Mm(double value)
		{
			return new Mm(value);
		}

		#region operators overloads
		public static bool operator <(Mm v1, Mm v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Mm v1, Mm v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Mm v1, Mm v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Mm v1, Mm v2)
		{
			return v1.Value != v2.Value;
		}

		public static Mm operator +(Mm v1, Mm v2)
		{
			return new Mm(v1.Value + v2.Value);
		}

		public static Mm operator -(Mm v1, Mm v2)
		{
			return new Mm(v1.Value - v2.Value);
		}

		public static Mm operator /(Mm v, double div)
		{
			return new Mm(v.Value / div);
		}

		public static Mm operator *(Mm v, double multi)
		{
			return new Mm(v.Value * multi);
		}

		public static Mm operator *(double multi, Mm v)
		{
			return new Mm(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Mm)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}


	/// <summary>
	/// 磅因
	/// </summary>
	public readonly struct Pt
	{
		public Pt(double value)
		{
			Value = value;
		}

		public double Value { get; }

		public static implicit operator Pt(double value)
		{
			return new Pt(value);
		}

		#region operators overloads
		public static bool operator <(Pt v1, Pt v2)
		{
			return v1.Value < v2.Value;
		}

		public static bool operator >(Pt v1, Pt v2)
		{
			return v1.Value > v2.Value;
		}

		public static bool operator ==(Pt v1, Pt v2)
		{
			return v1.Value == v2.Value;
		}

		public static bool operator !=(Pt v1, Pt v2)
		{
			return v1.Value != v2.Value;
		}

		public static Pt operator +(Pt v1, Pt v2)
		{
			return new Pt(v1.Value + v2.Value);
		}

		public static Pt operator -(Pt v1, Pt v2)
		{
			return new Pt(v1.Value - v2.Value);
		}

		public static Pt operator /(Pt v, double div)
		{
			return new Pt(v.Value / div);
		}

		public static Pt operator *(Pt v, double multi)
		{
			return new Pt(v.Value * multi);
		}

		public static Pt operator *(double multi, Pt v)
		{
			return new Pt(v.Value * multi);
		}

		#endregion

		#region override overloads
		public override bool Equals(object obj)
		{
			if (obj == null)
				return false;

			if ((obj.GetType() != this.GetType()))
				return false;

			var temp = (Pt)obj;
			//因为取差集，不用rank,就不写rank
			return this.Value == temp.Value;
		}
		public override int GetHashCode()
		{
			return Value.GetHashCode();
		}

		#endregion

	}

	#endregion

	#region converter
	/// <summary>
	/// 单位转换器
	/// </summary>
	public static class UnitConverter
	{
		public const double DefaultDpi = 72;

		#region Pixel

		public static Pixel ToPixel(this Inch inch) => inch.ToEmu().ToPixel();

		public static Inch ToInch(this Pixel pixel) => pixel.ToEmu().ToInch();

		#endregion

		#region Dxa

		public static Pt ToPt(this Dxa dxa)
		{
			return new Pt(dxa.Value / 20);
		}

		public static Dxa ToDxa(this Pt pt)
		{
			return new Dxa(pt.Value * 20);
		}

		public static Inch ToInch(this Dxa dxa)
		{
			return new Inch(dxa.Value / 72);
		}

		public static Dxa ToDxa(this Inch inch)
		{
			return new Dxa(inch.Value * 72);
		}

		#endregion

		#region Mm

		public static Cm ToCm(this Mm mm)
		{
			return new Cm(mm.Value / 10);
		}

		public static Mm ToMm(this Cm cm)
		{
			return new Mm(cm.Value * 10);
		}

		#endregion

		#region Pt

		public static Cm ToCm(this Pt pt)
		{
			return pt.ToEmu().ToCm();
		}

		public static Pt ToPt(this Cm cm)
		{
			return cm.ToEmu().ToPt();
		}

		public static Mm ToMm(this Pt pt)
		{
			return pt.ToCm().ToMm();
		}

		public static Pt ToPt(this Mm mm)
		{
			return mm.ToCm().ToPt();
		}

		public static Pt ToPt(this HalfPoint halfPoint)
		{
			return new Pt(halfPoint.Value / 2);
		}

		public static HalfPoint ToHalfPoint(this Pt pt)
		{
			return new HalfPoint(pt.Value * 2);
		}


		public static Pixel ToPixel(this Pt pt)
		{
			return new Pixel(pt.Value / 72 * DefaultDpi);
		}

		public static Pt ToPoint(this Pixel px)
		{
			return new Pt(px.Value * 72 / DefaultDpi);
		}

		#endregion

		#region Emu

		public static Emu ToEmu(this Inch inch)
		{
			return new Emu(inch.Value * 914400);
		}

		public static Inch ToInch(this Emu emu)
		{
			return new Inch(emu.Value / 914400);
		}

		public static Emu ToEmu(this Cm cm)
		{
			return new Emu(cm.Value * 360000);
		}

		public static Cm ToCm(this Emu emu)
		{
			return new Cm(emu.Value / 360000);
		}

		public static Emu ToEmu(this Mm cm)
		{
			return new Emu(cm.Value * 36000);
		}

		public static Dxa ToDxa(this Emu emu)
		{
			return new Dxa(emu.Value / 635);
		}

		public static Emu ToEmu(this Dxa dxa)
		{
			return new Emu(dxa.Value * 635);
		}

		public static Mm ToMm(this Emu emu)
		{
			return new Mm(emu.Value / 36000);
		}


		public static Emu ToEmu(this Pixel px)
		{
			return new Emu(px.Value * 914400 / DefaultDpi);
		}

		public static Pixel ToPixel(this Emu emu)
		{
			return new Pixel(emu.Value * DefaultDpi / 914400);
		}

		public static Emu ToEmu(this Pt pt)
		{
			return new Emu(pt.Value * 12700);
		}

		public static Pt ToPt(this Emu emu)
		{
			return new Pt(emu.Value / 12700);
		}

		#endregion
	}
	#endregion
}
